home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cocktail / front.lha / front / src / Rules.mi < prev    next >
Text File  |  1992-08-18  |  18KB  |  722 lines

  1. (* handle rule section *)
  2.  
  3. (* $Id: Rules.mi,v 2.2 1992/08/07 15:13:51 grosch rel $ *)
  4.  
  5. (* $Log: Rules.mi,v $
  6.  * Revision 2.2  1992/08/07  15:13:51  grosch
  7.  * allow several scanner and parsers; extend module Errors
  8.  *
  9.  * Revision 2.1  1991/11/21  14:47:50  grosch
  10.  * new version of RCS on SPARC
  11.  *
  12.  * Revision 2.0  91/03/08  18:26:28  grosch
  13.  * turned tables into initialized arrays (in C)
  14.  * moved mapping tokens -> strings from Errors to Parser
  15.  * changed interface for source position
  16.  * 
  17.  * Revision 1.4  90/06/11  18:45:25  grosch
  18.  * layout improvements
  19.  * 
  20.  * Revision 1.3     89/03/15  18:30:52  vielsack
  21.  * Fixed two bugs in AppendArtificialNode:
  22.  * If Expr = NIL now a tree with one empty alternative is build
  23.  * A local variable is used instead of Expr for searching in the tree
  24.  * 
  25.  * Revision 1.2     89/01/26  19:01:51  vielsack
  26.  * better position handling for nonterminals
  27.  * 
  28.  * Revision 1.1     89/01/23  15:50:27  vielsack
  29.  * by using AppendArtificialNode instead of MakeArtificialNode
  30.  * the tree order is the same as that of the input,
  31.  * this is necessary to handle LL(1) conflicts correctly
  32.  * 
  33.  * Revision 1.0     88/10/04  14:27:09  vielsack
  34.  * Initial revision
  35.  * 
  36.  *)
  37.  
  38. IMPLEMENTATION MODULE Rules;
  39.  
  40. FROM Lists    IMPORT MakeList, tList;
  41. FROM TokenTab    IMPORT Terminal, NonTerminal, Vocabulary, TokenType, MakeVoc,
  42.             SetNontermPos, MakeTerm, GetTokenType, SymbolToToken,
  43.             TokenError, PosType, GetPrio;
  44. FROM SYSTEM    IMPORT ADR, ADDRESS;
  45. FROM Memory    IMPORT Alloc;
  46. FROM Idents    IMPORT tIdent;
  47. FROM SYSTEM    IMPORT TSIZE;
  48. FROM Errors    IMPORT eFatal, eError, eIdent, eString, eInternal, ErrorMessageI;
  49. FROM Strings    IMPORT tString, ArrayToString;
  50. FROM Positions    IMPORT NoPosition;
  51.  
  52. CONST eNoOperator = 41; eTermLeft = 42; eTokenNotDecl = 32;
  53.  
  54. TYPE
  55.     Expression = POINTER TO Node;
  56.  
  57.     Node = 
  58.       RECORD
  59.     CASE Type: Operation OF
  60.       Plus, Star, Optional, Bracket:     (* unitaere Operationen *)
  61.         Son:    Expression;
  62.     | Separator, Alternative, Sequence:  (* binaere Operationen *)
  63.         LeSon,
  64.         RiSon:  Expression; 
  65.     | Action:
  66.         Act:    tList;
  67.     | TermLeaf, NonTermLeaf:
  68.         Token : Vocabulary;
  69.     END;
  70.     Position, 
  71.     SecondPos : PosType;
  72.     Special      : ADDRESS; 
  73.  
  74.     HasPrio      : BOOLEAN;   (* Erweiterung fuer Alternative *)
  75.     PRIOPos      : PosType;   (* zur Aufnahme einer Prioritaet *)
  76.     PrioSym      : tIdent;
  77.     PrioSymPos: PosType;
  78.       END;
  79.  
  80.     MRules = POINTER TO Rule;
  81.  
  82.     Rule = RECORD
  83.     Left     : NonTerminal;
  84.     LeftPos     : PosType;
  85.     ColonPos : PosType;
  86.     Right     : Expression;
  87.     PointPos : PosType;
  88.     Comment     : tList;
  89.     CommPos     : PosType;
  90.     CASE HasPrio : BOOLEAN OF
  91.       TRUE:
  92.         PRIOPos    : PosType;
  93.         Priority   : SHORTCARD;
  94.         PrioSym    : Terminal;
  95.         PrioSymPos : PosType;
  96.     END;
  97.     Next     : MRules;
  98.       END;
  99.  
  100.   VAR
  101.     RulesVars:
  102.       RECORD
  103.     RULESPos   : PosType;       (* Position von 'RULES' *)
  104.     Comment       : tList;
  105.     CommPos       : PosType;
  106.       END;
  107.  
  108.     StartMRule, (* zeigt auf 1. Regel *)
  109.     RMRule,    (* zeigt auf zuletzt gelesene Regel *)
  110.     WMRule    : MRules; (* zeigt auf zuletzt geschreibene Regel *)
  111.     OpenForReading : BOOLEAN; (* TRUE : GetRule erlaubt,
  112.                  FALSE : GetRule nur nach neuem InitRulesReading *)
  113.  
  114.   PROCEDURE MakeLeafNode
  115.      (sym: tIdent;
  116.       Pos: PosType) : Expression;
  117.  
  118.   (* Lege neuen Blattknoten an und liefere den Zeiger auf ihn
  119.      zurueck. *)
  120.  
  121.   VAR HNode : Expression;
  122.       Error : TokenError;
  123.       voc   : Vocabulary;
  124.  
  125.   BEGIN
  126.     HNode := Alloc(TSIZE(Node));
  127.     IF HNode = NIL THEN
  128.       ERROR ('MakeLeafNode: Heap overflow');
  129.     END;
  130.     HNode^.Position := Pos;
  131.     HNode^.Special  := NIL;
  132.     voc := MakeVoc(sym,Pos);
  133.     IF GetTokenType(voc) = Term THEN
  134.       HNode^.Type    := TermLeaf;
  135.       HNode^.Token   :=     voc;
  136.     ELSE 
  137.       HNode^.Type    := NonTermLeaf ;
  138.       HNode^.Token   :=     voc;
  139.     END;
  140.     RETURN HNode;
  141.   END MakeLeafNode;
  142.  
  143.  
  144.   PROCEDURE MakeActionNode (Act: tList; Pos: PosType) : Expression;
  145.   
  146.   (* Lege neuen Actionknoten an und liefere den Zeiger auf ihn 
  147.      zurueck *)
  148.   VAR HNode : Expression;
  149.       s        : tString;
  150.  
  151.   BEGIN
  152.     HNode := Alloc(TSIZE(Node));
  153.     IF HNode = NIL THEN
  154.       ArrayToString ('MakeActionNode : Heap overflow', s);
  155.       ErrorMessageI(eInternal, eFatal, Pos, eString, ADR(s));
  156.     END;
  157.     HNode^.Special  := NIL;
  158.     HNode^.Type := Action;
  159.     HNode^.Act := Act;
  160.     HNode^.Position := Pos;
  161.     RETURN HNode;
  162.   END MakeActionNode;
  163.  
  164.   
  165.   PROCEDURE MakeUnaryNode (Type: UnaryOperation; Pos: PosType; Son: Expression) : Expression;
  166.  
  167.   (* Bilde neuen Knoten der angegebenen Type mit gegebenem Sohn, 
  168.      und liefere den Zeiger auf ihn zurueck *)
  169.   VAR HNode : Expression;
  170.       s        : tString;
  171.  
  172.   BEGIN
  173.     HNode := Alloc(TSIZE(Node));
  174.     IF HNode = NIL THEN
  175.       ArrayToString(' MakeUnaryNode : Heap overflow', s);
  176.       ErrorMessageI (eInternal,eFatal, Pos, eString, ADR(s));
  177.     END;
  178.     HNode^.Special  := NIL;
  179.     HNode^.Type           := Type;
  180.     HNode^.Position   := Pos;
  181.     HNode^.Son     := Son;
  182.     RETURN HNode;
  183.   END MakeUnaryNode;
  184.  
  185.  
  186.   PROCEDURE MakeBracketNode
  187.     (Type   : BracketOperation;
  188.      Pos,
  189.      SecPos : PosType;
  190.      Son    : Expression) : Expression;
  191.  
  192.   (* Bilde neuen Knoten der angegebenen Type mit gegebenem Sohn,
  193.      und liefere den Zeiger auf ihn zurueck *)
  194.   VAR HNode : Expression;
  195.       s        : tString;
  196.  
  197.   BEGIN
  198.     HNode := Alloc(TSIZE(Node));
  199.     IF HNode = NIL THEN
  200.       ArrayToString ('MakeBracketNode : Heap overflow', s);
  201.       ErrorMessageI (eInternal,eFatal,Pos, eString, ADR (s));
  202.     END;
  203.     HNode^.Special  := NIL;
  204.     HNode^.Type           := Type;
  205.     HNode^.Position   := Pos;
  206.     HNode^.SecondPos     := SecPos;
  207.     HNode^.Son     := Son;
  208.     RETURN HNode;
  209.   END MakeBracketNode;
  210.   
  211.  
  212.   PROCEDURE MakeBinaryNode
  213.     (Type : BinaryOperation;
  214.      Pos : PosType;
  215.      LSon,
  216.      RSon: Expression) : Expression;
  217.  
  218.   (* Bilde neuen Knoten der angegebenen Type mit gegebenen Soehnen,
  219.      und liefere den Zeiger auf ihn zurueck *)
  220.   VAR HNode : Expression;  
  221.       s        : tString;
  222.  
  223.   BEGIN
  224.  
  225.     HNode := Alloc(TSIZE(Node));
  226.     IF HNode = NIL THEN
  227.       ArrayToString ('MakeBinaryNode : Heap overflow', s);
  228.       ErrorMessageI(eInternal,eFatal, Pos, eString, ADR (s));
  229.     END;
  230.     HNode^.Special  := NIL;
  231.     HNode^.Type           := Type;
  232.     HNode^.Position   := Pos;
  233.     HNode^.LeSon := LSon;
  234.     HNode^.RiSon := RSon;
  235.     IF Type = Alternative THEN
  236.       HNode^.HasPrio := FALSE;
  237.     END;
  238.     RETURN HNode;
  239.   END MakeBinaryNode;
  240.  
  241.   PROCEDURE MakePrioAlternativeNode
  242.      (Pos     : PosType;
  243.       LSon,
  244.       RSon     : Expression;
  245.       HasPrio     : BOOLEAN;
  246.       PRIOPos     : PosType;
  247.       PrioSym     : tIdent;
  248.       PrioSymPos : PosType) : Expression;
  249.   
  250.   VAR HNode : Expression;  
  251.       s : tString;
  252.  
  253.   BEGIN
  254.     HNode := Alloc(TSIZE(Node));
  255.     IF HNode = NIL THEN
  256.       ArrayToString ('MakePrioAlternativeNode : Heap overflow', s);
  257.       ErrorMessageI(eInternal,eFatal,Pos, eString, ADR(s));
  258.     END;
  259.     HNode^.HasPrio := HasPrio;
  260.     HNode^.PRIOPos := PRIOPos;
  261.     HNode^.PrioSym := PrioSym;
  262.     HNode^.PrioSymPos := PrioSymPos;
  263.     HNode^.Special  := NIL;
  264.     HNode^.Type           := Alternative;
  265.     HNode^.Position   := Pos;
  266.     HNode^.LeSon := LSon;
  267.     HNode^.RiSon := RSon;
  268.     RETURN HNode;
  269.   END MakePrioAlternativeNode;
  270.  
  271.  
  272.   PROCEDURE AppendArtificialNode (Pos, Pos2: PosType;
  273.                   VAR Expr: Expression; New: Expression);
  274.  
  275.   VAR
  276.     last, expr: Expression;
  277.  
  278.   BEGIN
  279.     IF (Expr = NoExpression) OR (GetNodeOperation (Expr) # ArtAlternative) THEN
  280.       Expr := MakeArtificialNode (Pos, Pos2, Expr, New);
  281.     ELSE
  282.       expr := Expr;
  283.       LOOP
  284.     last := expr^.RiSon;
  285.     IF GetNodeOperation (last) # ArtAlternative THEN EXIT END;
  286.     expr := last;
  287.       END;
  288.       expr^.RiSon := MakeArtificialNode (last^.Position, Pos2, last, New);
  289.     END;
  290.   END AppendArtificialNode;
  291.  
  292.  
  293.   PROCEDURE MakeArtificialNode
  294.      (Pos    : PosType;
  295.      SecPos : PosType;
  296.      LSon,
  297.      RSon: Expression) : Expression;
  298.  
  299.   (* Bilde neuen Knoten vom Typ ArtAlternative mit gegebenen Soehnen,
  300.      und liefere den Zeiger auf ihn zurueck *)
  301.   VAR HNode : Expression;  
  302.       s        : tString;
  303.  
  304.   BEGIN
  305.     HNode := Alloc(TSIZE(Node));
  306.     IF HNode = NIL THEN
  307.       ArrayToString ('MakeArtificialNode : Heap overflow', s);
  308.       ErrorMessageI(eInternal,eFatal,Pos,eString, ADR(s));
  309.     END;
  310.     HNode^.Special  := NIL;
  311.     HNode^.Type           := ArtAlternative;
  312.     HNode^.Position   := Pos;
  313.     HNode^.SecondPos  := SecPos;
  314.     HNode^.LeSon := LSon;
  315.     HNode^.RiSon := RSon;
  316.     RETURN HNode;
  317.   END MakeArtificialNode;
  318.  
  319.  
  320.   PROCEDURE PutNodeSpecial
  321.     (Expr:  Expression;
  322.      Spec: ADDRESS);
  323.   
  324.   (* Trage Knotensonderinformation ein *)
  325.  
  326.   BEGIN
  327.     IF Expr # NIL THEN
  328.       Expr^.Special := Spec;
  329.     ELSE
  330.       ERROR ('PutNodeSpecial : You tried to access an empty node');
  331.     END;
  332.   END PutNodeSpecial;
  333.      
  334.  
  335.   PROCEDURE MakeRule
  336.     (Left    : tIdent;
  337.      LeftPos    : PosType;
  338.      ColonPos    : PosType;
  339.      Right    : Expression;
  340.      Comment    : tList;
  341.      CommPos    : PosType;
  342.      PointPos    : PosType;
  343.      HasPrio    : BOOLEAN;
  344.      PRIOPos    : PosType;
  345.      PrioSym    : tIdent;
  346.      PrioSymPos : PosType);
  347.  
  348.   (* Trage eine neue Regel in die Datenstruktur ein *)
  349.   VAR HRule : MRules;
  350.       Error   : TokenError;
  351.       Leftvoc : Vocabulary;
  352.       voc     : Vocabulary;
  353.       s          : tString;
  354.  
  355.   BEGIN
  356.     OpenForReading := FALSE;
  357.     Leftvoc := MakeVoc(Left,LeftPos);
  358.     IF GetTokenType(Leftvoc) = Term THEN
  359.       (* Error: Links steht Terminal , Regel wird nicht eingetragen *) 
  360.       ErrorMessageI(eTermLeft ,eError,LeftPos, eIdent, ADR(Left));
  361.     ELSE
  362.       SetNontermPos (Left,LeftPos);
  363.       HRule := Alloc(TSIZE(Rule));
  364.       IF HRule = NIL THEN
  365.     ArrayToString('MakeRule : Heap overflow', s);
  366.     ErrorMessageI(eInternal,eFatal,LeftPos, eString, ADR (s));
  367.       END;
  368.       HRule^.Left     := Leftvoc;
  369.       HRule^.LeftPos  := LeftPos;
  370.       HRule^.ColonPos := ColonPos;
  371.       HRule^.PointPos := PointPos;
  372.       HRule^.Right    := Right;
  373.       HRule^.Comment  := Comment;
  374.       HRule^.CommPos  := CommPos;
  375.       HRule^.HasPrio  := HasPrio;
  376.       HRule^.Priority := 0; 
  377.       IF HasPrio THEN
  378.     HRule^.PRIOPos      := PRIOPos;
  379.     HRule^.PrioSymPos := PrioSymPos;
  380.     voc := SymbolToToken(PrioSym,Error);
  381.     IF Error # NoError THEN
  382.       ErrorMessageI(eTokenNotDecl,eError,PrioSymPos, eIdent, ADR(PrioSym));
  383.     ELSE
  384.       HRule^.PrioSym    := voc;
  385.       HRule^.Priority := GetPrio(voc);
  386.       IF HRule^.Priority = 0 THEN
  387.         ErrorMessageI(eNoOperator,eError,PrioSymPos,eIdent,ADR(PrioSym));
  388.       END;
  389.     END;
  390.       END;
  391.       IF WMRule <> NIL THEN
  392.     (* Nicht ListenAnfang *)
  393.     WMRule^.Next := HRule;
  394.       ELSE
  395.     StartMRule  := HRule;
  396.       END;
  397.       HRule^.Next := NIL;
  398.       WMRule       := HRule;
  399.     END;
  400.   END MakeRule;
  401.  
  402.  
  403.   PROCEDURE MakeRulesHeader
  404.     (RULESPos    : PosType;
  405.      Comment    : tList;
  406.      CommPos    : PosType);
  407.  
  408.   (* Speichere globale Information zum Abschnitt RULES ab *)
  409.  
  410.   BEGIN
  411.     RulesVars.RULESPos := RULESPos;
  412.     RulesVars.Comment  := Comment;
  413.     RulesVars.CommPos  := CommPos;
  414.   END MakeRulesHeader;
  415.  
  416.  
  417.   PROCEDURE InitRulesReading();
  418.  
  419.     (* Bereitet das Lesen vor. Der Lesezeiger wird auf die erste 
  420.        Regel eingestellt. Gibt es ueberhaupt keine Regeln, wird 
  421.        FALSE zurueck geliefert, sonst TRUE *)
  422.  
  423.     BEGIN
  424.       OpenForReading := TRUE;
  425.       RMRule := StartMRule;
  426.     END InitRulesReading; 
  427.  
  428.  
  429.  
  430.   PROCEDURE GetNodeOperation(Expr: Expression) : Operation;
  431.     BEGIN
  432.       IF Expr = NIL THEN
  433.     RETURN NoOperation;
  434.       ELSE
  435.     RETURN Expr^.Type;
  436.       END;
  437.     END GetNodeOperation;
  438.  
  439.  
  440.  
  441.   PROCEDURE GetLeafNode
  442.      (    Expr: Expression;
  443.      VAR Voc: Vocabulary;
  444.      VAR Pos: PosType);
  445.  
  446.   (* Liefere Information aus Blattknoten. *)
  447.  
  448.   BEGIN
  449.     IF (GetNodeOperation(Expr) # TermLeaf) AND 
  450.        (GetNodeOperation(Expr) # NonTermLeaf) THEN
  451.       ERROR ('GetLeafNode : Wrong Node Type');
  452.     END;
  453.     IF Expr <> NIL THEN
  454.       Voc := Expr^.Token;
  455.       Pos := Expr^.Position;
  456.     ELSE
  457.       ERROR ('GetLeafNode : Node empty');
  458.     END;
  459.   END GetLeafNode;
  460.  
  461.  
  462.   PROCEDURE GetActionNode
  463.      (     Expr:Expression;
  464.      VAR Act: tList;
  465.      VAR Pos: PosType);
  466.   
  467.   (* Liefere Information aus Actionknoten *)
  468.  
  469.   BEGIN
  470.     IF GetNodeOperation(Expr) # Action THEN
  471.       ERROR ('GetActionNode : Wrong Node Type');
  472.     END;
  473.     IF Expr <> NIL THEN
  474.       Act := Expr^.Act;
  475.       Pos := Expr^.Position;
  476.     ELSE
  477.       ERROR ('GetActionNode : Node empty');
  478.     END;
  479.   END GetActionNode;
  480.  
  481.   
  482.   PROCEDURE GetUnaryNode
  483.      (     Expr:Expression;
  484.      VAR Pos: PosType;
  485.      VAR Son: Expression);
  486.  
  487.   (* Liefere Information aus unaerem Knoten *) 
  488.  
  489.   BEGIN
  490.     IF (GetNodeOperation(Expr) # Star) AND 
  491.        (GetNodeOperation(Expr) # Plus) THEN
  492.       ERROR ('GetUnaryNode : Wrong Node Type');
  493.     END ;
  494.     IF Expr <> NIL THEN
  495.       Pos := Expr^.Position;
  496.       Son := Expr^.Son;
  497.     ELSE
  498.       ERROR ('GetUnaryNode : Node empty');
  499.     END;
  500.   END GetUnaryNode;
  501.   
  502.  
  503.   PROCEDURE GetBracketNode
  504.      (     Expr    : Expression;
  505.      VAR Pos,
  506.      SecPos : PosType;
  507.      VAR Son    : Expression);
  508.  
  509.   (* Liefere Information aus unaerem Knoten *) 
  510.  
  511.   BEGIN
  512.     IF (GetNodeOperation(Expr) # Bracket) AND 
  513.        (GetNodeOperation(Expr) # Optional) THEN
  514.       ERROR ('GetBracketNode : Wrong Node Type');
  515.     END ;
  516.     IF Expr <> NIL THEN
  517.       Pos := Expr^.Position;
  518.       SecPos := Expr^.SecondPos;
  519.       Son := Expr^.Son;
  520.     ELSE
  521.       ERROR ('GetBracketNode : Node empty');
  522.     END;
  523.   END GetBracketNode;
  524.   
  525.  
  526.   PROCEDURE GetBinaryNode
  527.      (     Expr: Expression;
  528.      VAR Pos : PosType;
  529.      VAR LSon,
  530.      RSon: Expression);
  531.  
  532.   (* Liefere Information aus binaerem Knoten *)
  533.  
  534.   BEGIN
  535.     IF (GetNodeOperation(Expr) # Sequence) AND 
  536.        (GetNodeOperation(Expr) # Separator) AND
  537.        (GetNodeOperation(Expr) # Alternative) AND
  538.        (GetNodeOperation(Expr) # ArtAlternative) THEN
  539.       ERROR ('GetBinaryNode : Wrong Node Type');
  540.     END ;
  541.     IF Expr <> NIL THEN
  542.       Pos  := Expr^.Position;
  543.       LSon := Expr^.LeSon;
  544.       RSon := Expr^.RiSon;
  545.     ELSE
  546.       ERROR ('GetBinaryNode : Node empty');
  547.     END; 
  548.   END GetBinaryNode;
  549.  
  550.   PROCEDURE GetPrioAlternativeNode
  551.      (      Expr         : Expression;
  552.       VAR Pos         : PosType;
  553.       VAR LSon         : Expression;
  554.       VAR RSon         : Expression;
  555.       VAR HasPrio    : BOOLEAN;
  556.       VAR PRIOPos    : PosType;
  557.       VAR PrioSym    : tIdent;
  558.       VAR PrioSymPos : PosType);
  559.  
  560.   BEGIN
  561.     IF (GetNodeOperation(Expr) # Alternative) THEN
  562.       ERROR ('GetPrioAlternativeNode : Wrong Node Type');
  563.     END ;
  564.     IF Expr <> NIL THEN
  565.       Pos  := Expr^.Position;
  566.       LSon := Expr^.LeSon;
  567.       RSon := Expr^.RiSon;
  568.       HasPrio := Expr^.HasPrio;
  569.       PRIOPos := Expr^.PRIOPos;
  570.       PrioSym := Expr^.PrioSym;
  571.       PrioSymPos := Expr^.PrioSymPos;
  572.     ELSE
  573.       ERROR ('GetPrioAlternativeNode : Node empty');
  574.     END; 
  575.   END GetPrioAlternativeNode;
  576.  
  577.  
  578.   PROCEDURE GetArtificialNode
  579.      (     Expr    : Expression;
  580.      VAR Pos    : PosType;
  581.      VAR SecPos : PosType;
  582.      VAR LSon,
  583.      RSon    : Expression);
  584.  
  585.   (* Liefere Information aus kuenstlichem Knoten *)
  586.  
  587.   BEGIN
  588.     IF (GetNodeOperation(Expr) # ArtAlternative) THEN
  589.       ERROR ('GetArtificialNode : Wrong Node Type');
  590.     END ;
  591.     IF Expr <> NIL THEN
  592.       Pos  := Expr^.Position;
  593.       SecPos := Expr^.SecondPos;
  594.       LSon := Expr^.LeSon;
  595.       RSon := Expr^.RiSon;
  596.     ELSE
  597.       ERROR ('GetArtificialNode : Node empty');
  598.     END; 
  599.   END GetArtificialNode;
  600.  
  601.  
  602.   PROCEDURE GetNodeSpecial
  603.     (Expr:  Expression) : ADDRESS;
  604.   
  605.   (* Liefere Knotensonderinformation *)
  606.  
  607.   BEGIN
  608.     IF Expr <> NIL THEN
  609.       RETURN Expr^.Special;
  610.     ELSE
  611.       ERROR ('GetNodeSpecial : Node empty');
  612.       RETURN NIL;
  613.     END
  614.   END GetNodeSpecial;
  615.      
  616.  
  617.   PROCEDURE GetRule
  618.     (VAR Left        : NonTerminal;
  619.      VAR LeftPos    : PosType;
  620.      VAR ColonPos   : PosType;
  621.      VAR Right        : Expression;
  622.      VAR Comment    : tList;
  623.      VAR CommPos    : PosType;
  624.      VAR PointPos   : PosType;
  625.      VAR HasPrio    : BOOLEAN;
  626.      VAR PRIOPos    : PosType;
  627.      VAR PrioSym    : Terminal;
  628.      VAR PrioSymPos : PosType) : BOOLEAN;
  629.  
  630.   (* Liefere naechste Regel bzw. FALSE falls es keine naechste Regel
  631.      mehr gibt. Die erste Regel kann nach Aufruf von  InitRuleReading
  632.      gelesen werden *)
  633.  
  634.   BEGIN
  635.     IF NOT OpenForReading THEN
  636.       ERROR ('GetRule : You must not read here');
  637.     END;
  638.     IF RMRule = NIL THEN
  639.       (* Am Ende der Liste angelangt *)
  640.       RETURN FALSE
  641.     ELSE
  642.       Left     := RMRule^.Left;
  643.       LeftPos  := RMRule^.LeftPos;
  644.       ColonPos := RMRule^.ColonPos;
  645.       PointPos := RMRule^.PointPos;
  646.       Right    := RMRule^.Right;
  647.       Comment  := RMRule^.Comment;
  648.       CommPos  := RMRule^.CommPos;
  649.       IF RMRule^.HasPrio THEN
  650.     PRIOPos       := RMRule^.PRIOPos;
  651.     PrioSym       := RMRule^.PrioSym;
  652.     PrioSymPos := RMRule^.PrioSymPos;
  653.       ELSE
  654.     PRIOPos .Line    := 0;
  655.     PRIOPos .Column := 0;
  656.     PrioSym     := 0;
  657.     PrioSymPos.Line      := 0;
  658.     PrioSymPos.Column := 0;
  659.       END;
  660.       HasPrio  := RMRule^.HasPrio;
  661.       (* Weiterschalten *)
  662.       RMRule := RMRule^.Next;
  663.       RETURN TRUE;
  664.     END;
  665.   END GetRule;
  666.  
  667.   PROCEDURE GetEssentialRule
  668.     (VAR Left        : NonTerminal;
  669.      VAR Right        : Expression;
  670.      VAR HasPrio    : BOOLEAN) : BOOLEAN;
  671.  
  672.   (* Liefere naechste Regel bzw. FALSE falls es keine naechste Regel
  673.      mehr gibt. Die erste Regel kann nach Aufruf von  InitRuleReading
  674.      gelesen werden. Die Prozedur kann im Wechsel mit GetRule ver-
  675.      wendet werden.*)
  676.  
  677.   BEGIN
  678.     IF NOT OpenForReading THEN
  679.       ERROR ('GetEssentialRule : You must not read here');
  680.     END;
  681.     IF RMRule = NIL THEN
  682.       (* Am Ende der Liste angelangt *)
  683.       RETURN FALSE
  684.     ELSE
  685.       Left     := RMRule^.Left;
  686.       Right    := RMRule^.Right;
  687.       HasPrio  := RMRule^.HasPrio ;
  688.       (* Weiterschalten *)
  689.       RMRule := RMRule^.Next;
  690.       RETURN TRUE;
  691.     END;
  692.   END GetEssentialRule;
  693.  
  694.   PROCEDURE GetRulesHeader (VAR RULESPos: PosType; VAR Comment: tList; VAR CommPos: PosType);
  695.  
  696.   (* Liefere globale Information zum Abschnitt RULES *)
  697.  
  698.   BEGIN
  699.     RULESPos := RulesVars.RULESPos;
  700.     Comment  := RulesVars.Comment;
  701.     CommPos  := RulesVars.CommPos;
  702.   END GetRulesHeader;
  703.  
  704.   PROCEDURE ERROR (a : ARRAY OF CHAR);
  705.   VAR s : tString;
  706.   BEGIN
  707.     ArrayToString (a, s);
  708.     ErrorMessageI (eInternal, eFatal, NoPosition, eString, ADR(s));
  709.   END ERROR;
  710.  
  711. BEGIN
  712.  RMRule := NIL;
  713.  WMRule := NIL;
  714.  StartMRule := NIL;
  715.  RulesVars.RULESPos.Line   := 0;
  716.  RulesVars.RULESPos.Column := 0;
  717.  MakeList (RulesVars.Comment);
  718.  RulesVars.CommPos.Line      := 0;
  719.  RulesVars.CommPos.Column := 0;
  720.  NoExpression := NIL;
  721. END Rules.
  722.